package org.jeecg.modules.cas.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.IscSessionPolicy;
import org.jeecg.common.constant.enums.SysAuthType;
import org.jeecg.common.constant.enums.SysLogOperateType;
import org.jeecg.common.constant.enums.SysLogType;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.sm.SmManager;
import org.jeecg.common.util.sm.UserKeyInfo;
import org.jeecg.config.IscConfig;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.IUserService;
import org.jeecg.modules.system.util.IscUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.sgcc.isc.ualogin.client.util.IscSSOResourceUtil;
import com.sgcc.isc.ualogin.client.vo.IscSSOUserBean;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * CAS单点登录客户端登录认证
 * </p>
 *
 * @Author zhoujf
 * @since 2018-12-20
 */
@Slf4j
@RestController
@RequestMapping("/cas/client")
public class CasClientController {

	@Autowired
	private IUserService userService;
	@Autowired
	private ISysDepartService sysDepartService;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private ISysBaseAPI sysBaseAPI;

	@Value("${cas.prefixUrl}")
	private String prefixUrl;
	@Value("${mesh.loginSingle:false}")
	private Boolean loginSingle;

	@GetMapping("/getCurrentUserName")
	public Result<String> getCurrentUseName(HttpServletRequest request) throws Exception {
		Result<String> result = new Result<>();
		IscSSOUserBean iscSSOUserBean = IscSSOResourceUtil.getIscUserBean(request);
		if (iscSSOUserBean != null) {
			result.setResult(iscSSOUserBean.getIscUserSourceId());
		}
		return result;
	}

	@GetMapping("/validateLogin")
	public Object validateLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Result<JSONObject> result = new Result<JSONObject>();
		log.info("Rest api login.");
		try {
			IscSSOUserBean iscSSOUserBean = IscSSOResourceUtil.getIscUserBean(request);
			if (iscSSOUserBean == null || StringUtils.isBlank(iscSSOUserBean.getIscUserId())) {
				throw new Exception("user not login isc");
			}

			log.info("========-------token----username---" + iscSSOUserBean.getIscUserSourceId() + "=======userId:" + iscSSOUserBean.getIscUserId());
			// 1. 校验用户是否有效
			SysUser sysUser = userService.getUserByName(iscSSOUserBean.getIscUserSourceId());
			if (sysUser == null) {
				sysUser = userService.syncUser(iscSSOUserBean.getIscUserId(), iscSSOUserBean.getIscUserSourceId());
			} else {
				if (StringUtils.isBlank(sysUser.getThirdId())) {
					sysUser.setThirdId(iscSSOUserBean.getIscUserId());
					sysUser.setThirdType(SysAuthType.ISC.getName());
					userService.updateById(sysUser);
				}
			}

			log.info("----sysUser----" + sysUser);
			result = userService.checkUserIsEffective(sysUser);
			log.info("----result----" + result);
			if (!result.isSuccess()) {
				log.debug("----user----result" + result);
				return result;
			}
			//删除以前同用户的token
			log.info("delete user_tokens begin,pr");

			log.info("delete user_tokens success");
			String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
			// 设置超时时间
			log.info("----user----sign" + token);
			log.info("-----isc----session-policy");
			IscSessionPolicy sessionPolicy = getPolicy();
			redisUtil.set(CommonConstant.PREFIX_USER_TOKEN +sysUser.getUsername() +"_" + token, token);
			if (sessionPolicy != null && sessionPolicy.getSessionTimeout() != null) {
				redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN +sysUser.getUsername() +"_" + token, sessionPolicy.getSessionTimeout());
				IscSessionPolicy.sessionTimeOut = sessionPolicy.getSessionTimeout();
			} else {
				redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + sysUser.getUsername() +"_" + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
			}
			
			JSONObject obj = new JSONObject();
			
			// 获取用户部门信息
//			List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
//			obj.put("departs", departs);
//			log.info("----user----sign" + departs);
//			if (departs == null || departs.size() == 0) {
//				obj.put("multi_depart", 0);
//			} else if (departs.size() == 1) {
//				userService.updateUserDepart(iscSSOUserBean.getIscUserSourceId(), departs.get(0).getOrgCode());
//				obj.put("multi_depart", 1);
//			} else {
//				obj.put("multi_depart", 2);
//			}
			
			
			obj.put("token", token);
			obj.put("userInfo", sysUser);
			result.setResult(obj);
			result.success("登录成功");
			
			sysBaseAPI.addLog("用户名: " + sysUser.getUsername() + ",登录成功！", SysLogType.LOGIN, SysLogOperateType.LOGIN, sysUser.getId());

			log.info("========-------token----result---success");

			// 国密 start
			String publicKey = initSm(sysUser.getId(), sysUser.getUsername());
			response.addHeader(SmManager.SM2_HEADER, publicKey);
			request.setAttribute(SmManager.SM2_HEADER, publicKey);
			// 国密 end
			if(loginSingle != null && loginSingle) {
				String tokenKey = CommonConstant.PREFIX_USER_TOKEN +sysUser.getUsername()+"_"+token;
				boolean hasOthers = redisUtil.hasOtherUser(CommonConstant.PREFIX_USER_TOKEN +sysUser.getUsername(), tokenKey);
				//redisUtil.batchDel(CommonConstant.PREFIX_USER_TOKEN +sysUser.getUsername());
				if(hasOthers) {
					result.setSuccess(true);
					result.setMessage("该用户已登录");
					return new HttpEntity<>(result);
				}
			}
		} catch (Exception e) {
			log.error("登录报错：" + e, e);
			result.error500(e.getMessage());
		}
		return new HttpEntity<>(result);
	}

	private IscSessionPolicy getPolicy() {
		IscUtil iscUtil = SpringContextUtils.getBean(IscUtil.class);
		String seesionPolicyUrl = IscConfig.getIscSsoPath() + "loadSessionPolicy?appid=" + String.valueOf(IscConfig.getIscAppId());
		try {
			log.info("ISC session policy:" + "    url:" + seesionPolicyUrl);
			RestTemplate restTemplate = new RestTemplate();
			String res = restTemplate.getForObject(seesionPolicyUrl, String.class);
			IscSessionPolicy policy = JSONObject.parseObject(res, IscSessionPolicy.class);
			return policy;
		} catch (Exception e) {
			log.error("get----session---policy--error:" + e);
		}
		return null;
	}

	private String initSm(String userId, String username) {
		log.info("----sm manager init error ----");
		String publicKey = null;
		try {
			UserKeyInfo userKey = new UserKeyInfo();
			String key = SmManager.SM + userId;
			Map<String, String> keypair = SmManager.generateKeypair();
			String privateKey = keypair.get("private");
			publicKey = keypair.get("public");
			userKey.setUserKey(key);
			userKey.setSm2PrivateKey(privateKey);
			userKey.setSm2PublicKey(publicKey);
			redisUtil.set(userKey.getUserKey(), userKey);
			log.info("[SM][CasClientController][initSm] 生成用户{}【{}】的秘钥对，publicKey:{}, privateKey:{}", username, userId, publicKey, privateKey);
		} catch (Exception e) {
			log.error("----sm manager init error ----");
		}
		return publicKey;
	}

}
